from manimlib import *
from numpy import flip, insert

LV,QL,QH,JH='#75cfb8','#bbdfc8','#f0e5d8','#ffc478'

class p1(Scene):
    def construct(self):
        # self.add(NumberPlane())
        # self.camera.frame.scale(0.7)
        x=ValueTracker(4)
        t=(x.get_value()+1)/2
        a,b,c,d=[-t,t,0],[t,t,0],[t,-t,0],[-t,-t,0]
        a_,b_,c_,d_=d+RIGHT,a+DOWN,b+LEFT,c+UP
        #
        ac_,bc_,bd_,cd_,ca_,da_,db_,ab_=Line(a,c_),Line(b,c_),Line(b,d_),Line(c,d_),Line(c,a_),Line(d,a_),Line(d,b_),Line(a,b_)
        aa_,bb_,cc_,dd_=Line(a,a_),Line(b,b_),Line(c,c_),Line(d,d_)
        #
        s=Square(2*t)
        self.add(s)
        #
        for i in range(4):
            self.add(
                Line(a,d+np.array([1,0,0])).rotate_about_origin(PI/2*i),
            )
        self.add(
            Tex('1').next_to(bc_,UP),
            Tex('1').next_to(cd_),
            Tex('1').next_to(da_,DOWN),
            Tex('1').next_to(ab_,LEFT),
            Tex('x').next_to(ac_,UP),
            Tex('x').next_to(bd_),
            Tex('x').next_to(ca_,DOWN),
            Tex('x').next_to(db_,LEFT),
            Tex('A').next_to(a,UL),
            Tex('B').next_to(b,UR),
            Tex('C').next_to(c,DR),
            Tex('D').next_to(d,DL),
            Tex('A^\prime').next_to(a_,DOWN),
            Tex('B^\prime').next_to(b_,LEFT),
            Tex('C^\prime').next_to(c_,UP),
            Tex('D^\prime').next_to(d_),
            Polygon(line_intersection(aa_.get_start_and_end(),bb_.get_start_and_end()),line_intersection(bb_.get_start_and_end(),cc_.get_start_and_end()),line_intersection(cc_.get_start_and_end(),dd_.get_start_and_end()),line_intersection(dd_.get_start_and_end(),aa_.get_start_and_end())).set_fill(LV,1)
        )
        self.wait()

class p2(Scene):
    def construct(self):
        # self.add(NumberPlane())
        # self.camera.frame.scale(0.7)
        x=ValueTracker(1)
        high=4
        ab=Line(LEFT,RIGHT).shift(UP*high/2+RIGHT).scale(3)
        cd=ab.copy().shift(DOWN*high+LEFT*2)
        a,b,c,d=ab.get_left(),ab.get_right(),cd.get_right(),cd.get_left()
        abcd=Polygon(a,b,c,d).set_fill(JH,1)
        e=a+DOWN*high
        abce=Polygon(a,b,c,e).set_fill(JH,1)
        ade=Polygon(a,d,e).set_fill(LV,1).add_updater(lambda m:m.become(
            Polygon(a,d,e).set_fill(LV,1).shift(RIGHT*x.get_value()*6+LEFT*6)
        ))
        # label
        b_h=Brace(abcd,LEFT).add_updater(lambda m:m.become(
            Brace(abcd,LEFT).shift(RIGHT*x.get_value()*2+LEFT*2)
        ))
        b_b=Brace(cd,DOWN).add_updater(lambda m:m.become(
            Brace(cd,DOWN).shift(RIGHT*x.get_value()*2+LEFT*2)
        ))
        t_h=Tex('h')
        t_b=Tex('b')
        always(t_b.next_to,b_b,DOWN)
        always(t_h.next_to,b_h,LEFT)
        self.add(abce,abcd,t_b,t_h,b_h,b_b,)
        self.wait()
        self.play(Create(ade))
        self.remove(abcd)
        self.play(x.animate.set_value(2))
        self.wait()
        self.play(x.animate.set_value(1))
        self.add(abcd,ade)
        self.play(Uncreate(ade))

class p3(Scene):
    def construct(self):
        self.add(NumberPlane().set_color(GRAY))
        # self.camera.frame.scale(0.7)
        x=ValueTracker(1)
        high=4
        ab=Line(LEFT,RIGHT).shift(UP*high/2+RIGHT).scale(3)
        cd=ab.copy().shift(DOWN*high+LEFT*2)
        ab_=ab.copy().shift(LEFT*2)
        a,b,c,d=ab.get_left(),ab.get_right(),cd.get_right(),cd.get_left()
        a_,b_=ab_.get_left(),ab_.get_right()
        rectangle=Polygon(a_,b_,c,d).set_fill(LV,0.7)
        tri_JH=Polygon(b,c,d).set_fill(JH,0.7)
        self.add(rectangle,tri_JH)
        tri_LV=Polygon(a,a_,d).set_fill(LV,0.7)
        self.play(Create(tri_LV))
        self.remove(rectangle)
        t=Polygon(a,b_,c,d).set_fill(LV,0.7)
        self.add(t)
        self.play(tri_LV.animate.shift(RIGHT*6))
        self.wait()
        self.play(tri_LV.animate.shift(LEFT*6))
        self.remove(t)
        self.add(rectangle)
        self.remove(tri_JH)
        self.add(tri_JH)
        self.play(Uncreate(tri_LV))
        self.wait()

class p4(Scene):
    def construct(self):
        # self.add(NumberPlane())
        # self.camera.frame.scale(0.7)
        x=ValueTracker(0)
        high=4
        ab=Line(LEFT,RIGHT).shift(UP*2+LEFT*1.5)
        cd=Line(LEFT*3,RIGHT*2).shift(DOWN*2+LEFT*1.5)
        a,b,c,d=ab.get_left(),ab.get_right(),cd.get_right(),cd.get_left()
        a_=a+DOWN*high
        abcd=Polygon(a,b,c,d).set_fill(LV,1)
        self.add(abcd)
        b_b1=Brace(ab,UP)
        b_h=Brace(abcd,LEFT).add_updater(lambda m:m.become(
            Brace(Line(d,d+UP*high),LEFT).shift(RIGHT*2*x.get_value())
        ))
        b_b2=Brace(cd,DOWN)
        t_b2=Tex('b_2').next_to(b_b2,DOWN)
        self.add(b_b1,b_h,b_b2,t_b2,
            Tex('b_1').next_to(b_b1,UP),
            always(Tex('h').next_to,b_h,LEFT),
        )
        abcd_JH=abcd.copy().set_fill(JH,1)
        self.play(abcd_JH.animate.shift(RIGHT*4))
        self.play(Rotate(abcd_JH,PI))
        b_b2_=Brace(abcd_JH,UP)
        self.play(Transform(VGroup(b_b2,t_b2),VGroup(b_b2_,Tex('b_2').next_to(b_b2_,UP))))
        tri=Polygon(a,a_,d).add_updater(lambda m:m.become(
            Polygon(a,a_,d).set_fill(LV,1).shift(RIGHT*7*x.get_value()
        )))
        self.play(Create(tri))
        abcd.become(Polygon(a,b,c,a_).set_fill(LV,1))
        self.play(x.animate.set_value(1))
        self.wait(3)